import 'dart:io';

import 'package:aio/aio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:app/generated/app_strings.dart';
import 'package:app/src/config/app_data_config.dart';
import 'package:app/src/config/app_key.dart';
import 'package:app/src/http/bean/clockin/attendances.dart';
import 'package:app/src/http/bean/clockin/clokin_subdata_type.dart';
import 'package:app/src/http/bean/wroks/attachment_bean.dart';
import 'package:app/src/ui/app_ui.dart';
import 'package:app/src/ui/dialog/dailog.dart';
import 'package:app/src/ui/dialog/show_dialog_with_class.dart';
import 'package:app/src/ui/route/helper/route_helper.dart';
import 'package:sdk_plugin/baidu_map_utils.dart';

import '../../../http/bean/clockin/clock_in.dart';
import '../../../http/bean/clockin/clockin_point_range.dart';
import '../../../http/model/clokin_model.dart';
import '../../../http/model/user_model.dart';
import '../../../manager/user_manager.dart';
import '../../../utils/app_baidu_map_utils.dart';
import '../../../utils/image_path_utils.dart';

// import 'package:sdk_';
// import 'package:sdk_plugin/sdk_plugin.dart';
///打卡签到
///erp 班组管理设置是否需要拍照。
///erp 工厂管理设置考勤范围。
class ClockinRoute extends StatefulWidget {
  @override
  _State createState() => _State();
}

class _State extends State<ClockinRoute> {
  _Presenter presenter = _Presenter();

  @override
  void initState() {
    super.initState();
    presenter?.setState = setState;

    ///获取经纬度度，班组班次信息。（获取最新的打卡记录）
    presenter?.getAppSignInHandlerWithGetPointRange(context);

    ///开启定位
    AppBaiduMapUtils.startLocation(context, (value) {
      // print("=================位置${value.address}");
      presenter?.location = value;
      if (presenter?.clokinData == null) {
        ///获取经纬度度，班组班次信息。
        presenter?.getAppSignInHandlerWithGetPointRange(context,
            responseCallbackWithBool: (value) {
          presenter?.setState?.call(() {});
        }, isEnableLoad: false);
      } else {
        //fixme 定位刷新，界面也实时刷新。
        presenter?.setState?.call(() {});
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    //保存班组班次
    presenter?.saveLocalGroup();
    //停止定位
    AppBaiduMapUtils.stopLocation(context);
    presenter?.location = null;
  }

  @override
  Widget build(BuildContext context) {
    px.init(context);
    var scaffold = Scaffold(
      backgroundColor: AppColors.backgroundColorWithWhite,
      appBar: AppBar(
        backgroundColor: AppColors.backgroundColorWithTitle,
        elevation: 0,
        leading: AppUi.getBack(context, () {
          return false;
        }, color: Colors.white),
        centerTitle: true,
        leadingWidth: 36,
        titleSpacing: 0,
        //打卡签到
        title: Text(
          AppStrings.of(context).ClockIn,
          style: AppStyle.textStyleWithTitleWhite(),
        ),
      ),
      body: Material(
          color: AppColors.backgroundColorWithWhite, child: _body(context)),
    );
    return WillPopScope(
      child: scaffold,
      onWillPop: () async {
        return true;
      },
    );
  }

  Widget _body(BuildContext context) {
    return Scrollbar(
      child: SingleChildScrollView(
        physics: BouncingScrollPhysics(),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            _tileWeek(context),
            _head(context),
            Divider(
              height: 1,
              color: ColorUtils.parseColor("#cccccc"),
            ),
            _class(context),
            //班组班次
            _shift(context),
            //圆形打卡按钮
            _clockin(context),
            //底部已打卡或未打卡
            _clockinInfo(context)
          ],
        ),
      ),
    );
  }

  ///顶部时间
  Widget _tileWeek(BuildContext context) {
    var dateTime = DateTimeUtils.getDateTimeFormat(dateAndTime: false);
    var week = DateTimeUtils.getDateTimeWithWeek();
    var container = Container(
      color: ColorUtils.parseColor("#66a2f4"),
      alignment: Alignment.center,
      height: px.x(180),
      child: Row(
        children: [
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(left: px.x(60)),
              child: Text(
                dateTime,
                style: AppStyle.textStyleWithTimeWhite(),
              ),
            ),
            flex: 2,
          ),
          Expanded(
              child: Container(
            child: Text(
              week,
              style: AppStyle.textStyleWithTimeWhite(),
            ),
            alignment: Alignment.centerRight,
            padding: EdgeInsets.only(right: px.x(60)),
          ))
        ],
      ),
    );
    var padding = Padding(
        child: container,
        padding: EdgeInsets.only(
            left: px.x(90), right: px.x(90), top: 0, bottom: px.x(60)));
    return Container(
      child: padding,
      color: AppColors.backgroundColorWithTitle,
      alignment: Alignment.center,
      width: px.screenWidth(),
    );
  }

  ///头像
  Widget _head(BuildContext context) {
    //头像
    var row1 = Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        InkWell(
          child: Card(
            child: Builder(
              builder: (context) {
                var imageUrl = UserManager.getUserInfo()?.getPersonPictureUrl();
                var imagePath = ImagePathUtils.getImageLogo();
                return FImage(
                  imageUrl,
                  placeholder: imagePath,
                  width: px.x(160),
                  height: px.x(160),
                  fit: BoxFit.cover,
                  isCache: true,
                );
              },
            ),
            shadowColor: Colors.blue,
            //阴影颜色
            elevation: 0,
            //阴影长度
            shape: RoundedRectangleBorder(
                side: BorderSide(
                    color: ColorUtils.parseColor("#999999"), width: 1),
                borderRadius: BorderRadius.all(Radius.circular(90))),
            //RoundedRectangleBorder圆角矩形边框
            clipBehavior:
                Clip.antiAlias, // Clip.antiAlias 圆角具备切割能力;Clip.none圆角不具备切割能力。
          ),
        ),
        SizedBox(
          width: px.x(29),
        ),
        Text(
          '${UserManager.getUserInfo()?.PersonName}',
          style: AppStyle.textStyleWithTitle(),
        ),
      ],
    );
    //打卡记录
    var column1 = Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Image.asset(
          ImagePathUtils.getPathWithImageClockin('02.png'),
          width: px.x(70),
        ),
        Text(
          AppStrings.of(context).ClockInRecord,
          style: AppStyle.textStyleWithLittle(),
        ),
      ],
    );
    var container = Container(
      padding: EdgeInsets.only(left: px.x(60)),
      alignment: Alignment.centerLeft,
      height: px.x(240),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Expanded(child: row1),
          Expanded(
              child: Align(
            child: Padding(
              padding: EdgeInsets.only(right: px.x(60)),
              child: InkWell(
                child: column1,
                onTap: () {
                  //打卡记录
                  AppRouteHelper.goClockinRecordRoute(context);
                },
              ),
            ),
            alignment: Alignment.centerRight,
          ))
        ],
      ),
    );
    return container;
  }

  ///班组
  Widget _class(BuildContext context) {
    StateSetter? _setState = null;
    var row = Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Padding(
          padding:
              EdgeInsets.only(left: px.x(30), top: px.x(20), bottom: px.x(20)),
          child: Image.asset(
            ImagePathUtils.getPathWithImageClockin("03.png"),
            width: px.x(80),
            height: px.x(80),
          ),
        ),
        Expanded(child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            _setState = setState;
            Text text;
            if (presenter?.GroupBcInfo?.GroupName != null) {
              text = Text(
                presenter!.GroupBcInfo!.GroupName!,
                style: TextStyle(
                  color: ColorUtils.parseColor("#194e96"),
                  fontSize: 16,
                ),
              );
            } else {
              text = Text(
                AppStrings.of(context).selectTeam,
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 16,
                ),
              );
            }
            return Container(
              child: text,
              alignment: Alignment.center,
              padding: EdgeInsets.only(right: px.x(60)),
            );
          },
        )),
        Padding(
          padding:
              EdgeInsets.only(right: px.x(30), top: px.x(20), bottom: px.x(20)),
          child: Image.asset(
            ImagePathUtils.getPathWithImageClockin("04.png"),
            width: px.x(30),
            height: px.x(50),
          ),
        ),
      ],
    );
    var container = Container(
      alignment: Alignment.center,
      decoration: BoxDecoration(
          color: ColorUtils.parseColor("d9e8fc"),
          borderRadius: BorderRadius.all(Radius.circular(10.0))),
      height: px.x(120),
      width: px.x(750),
      child: row,
    );
    var inkwell = InkWell(
      child: container,
      onTap: () {
        //选择班组
        presenter?.chooseGroupBcInfo(context);
      },
    );
    return Padding(
      padding: EdgeInsets.only(top: px.y(80)),
      child: inkwell,
    );
  }

  ///班次
  Widget _shift(BuildContext context) {
    List<MyAttendances>? content = presenter?.GroupBcInfo?.Attendances;
    if (presenter?.isOnWork() ?? false) {
      //fixme 用户正处于上班打卡状态。不能选择其他班次。
      if (presenter?.attendances != null) {
        content = [presenter!.attendances!];
      }
    }
    if (StringUtils.isEmpty(content)) {
      return AppUi.getEmptyView();
    }
    // List<ShiftBean>? content = [];
    // ShiftBean shift1 = ShiftBean();
    // shift1.Name = "早班";
    // shift1.StartTime = "08:00";
    // content.add(shift1);
    // ShiftBean shift2 = ShiftBean();
    // shift2.Name = "中班";
    // shift2.StartTime = "17:00";
    // content.add(shift2);
    // ShiftBean shift3 = ShiftBean();
    // shift3.Name = "晚班";
    // shift3.StartTime = "00:00";
    // content.add(shift3);
    if (presenter?.attendances == null) {
      var time = DateTimeUtils.getDateTimeWithDouble();
      //var time =22.0;
      if (content!.length == 1) {
        presenter?.attendances = content[0];
      } else {
        content?.forEach((element) {
          element.time(time);
          if (element.isSelected) {
            presenter?.attendances = element;
          }
        });
        if (presenter?.attendances == null) {
          double difference = 24;
          content?.forEach((element) {
            if (element.difference < difference) {
              difference = element.difference;
              presenter?.attendances = element; //取上班时间差，最近的班次。
            }
          });
        }
      }
    }
    return StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        List<Widget> children = [];
        content?.forEach((element) {
          Container container;
          if (presenter?.attendances?.getAttendanceKey() ==
              element?.getAttendanceKey()) {
            //选中
            Text text = Text(
              element.getWorkTypeNameAll(),
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.white, fontSize: 16),
            );
            container = Container(
                child: text,
                alignment: Alignment.center,
                padding:
                    EdgeInsets.only(top: 5, bottom: 5, left: 15, right: 15),
                decoration: BoxDecoration(
                  color: ColorUtils.parseColor("#408BF1"),
                  borderRadius: BorderRadius.all(Radius.circular(5)),
                ));
          } else {
            Text text = Text(
              element.getWorkTypeNameAll(),
              textAlign: TextAlign.center,
              style: TextStyle(
                color: Colors.black,
                fontSize: 16,
              ),
            );
            container = Container(
                child: text,
                alignment: Alignment.center,
                padding:
                    EdgeInsets.only(top: 5, bottom: 5, left: 15, right: 15),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.all(Radius.circular(5)),
                  border: Border.all(
                      color: ColorUtils.parseColor("#cccccc"), width: 1),
                ));
          }
          var inkWell = InkWell(
            child: container,
            onTap: () {
              if (presenter?.isOnWork() ?? false) {
                //上班已打卡，就不能再选择其他的班次了。
                if (presenter?.attendances?.AttendanceId !=
                    element.AttendanceId) {
                  //你已在其他班次打卡签到，请先签出再选择其他班次。
                  String content = AppStrings.of(context).anotherFlight;
                  showDialogWithInfo(context, content: content);
                }
              } else {
                //上班未打卡
                presenter?.setState?.call(() {
                  presenter?.attendances = element;
                });
              }
            },
          );
          children.add(Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Container(
                child: inkWell,
                margin: EdgeInsets.only(left: 6, right: 6, top: 20),
              )
            ],
            mainAxisSize: MainAxisSize.min,
          ));
        });
        // var row = Row(
        //   mainAxisAlignment: MainAxisAlignment.center,
        //   crossAxisAlignment: CrossAxisAlignment.center,
        //   children: children,
        // );
        return Container(
          alignment: Alignment.center,
          child: ListView(
            children: children,
            scrollDirection: Axis.horizontal,
            shrinkWrap: true,
          ),
          width: px.screenWidth(),
          height: 80,
        );
      },
    );
  }

  ///打卡
  StateSetter? locationSetState = null;

  ///圆形打卡按钮
  Widget _clockin(BuildContext context) {
    return StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        locationSetState = setState;
        String _string;
        if (presenter?.isGoToWork() ?? false) {
          _string = AppStrings.of(context).punchIn; //上班打卡
        } else {
          _string = AppStrings.of(context).punchOut; //下班打卡
        }
        var attendance = AppStrings.of(context).attendance; //已进入考勤范围
        var attendanceTextColor = ColorUtils.parseColor("91becb");
        var color_circle_out = ColorUtils.parseColor("#9FC5F8"); //外圈正常颜色
        var color_circle_in = ColorUtils.parseColor("#408BF1"); //内圈正常颜色
        if (presenter.isField()) {
          //外勤
          _string = AppStrings.of(context).fieldClock; //外勤打卡
          if (presenter?.isGoToWork() ?? false) {
            _string = AppStrings.of(context).fieldClockIn; //外勤签到
          } else {
            _string = AppStrings.of(context).fieldClockOut; //外勤签退
          }
          attendance = AppStrings.of(context).notAttendance; //未进入考勤范围
          attendanceTextColor = ColorUtils.parseColor("ef5a25");
          color_circle_out = ColorUtils.parseColor("#C5D1E1"); //外圈正常颜色
          color_circle_in = ColorUtils.parseColor("#90A2BA"); //内圈正常颜色
          if (presenter?.location?.getAddrStr() != null) {
            presenter?.adress = presenter!.location!.getAddrStr();
            attendance += ":" + presenter!.adress!; //fixme 具体位置不显示
          }
        } else {
          if (presenter.isLessthan_100) {
            //范围低于100米；直接显示工厂地址名称。
            var FactoryName = AppDataConfig.getFactory()?.FactoryName ?? "";
            presenter?.adress = FactoryName;
            attendance += ":" + FactoryName;
          } else {
            presenter?.adress = presenter!.location!.getAddrStr();
            attendance += ":" + presenter!.adress!; //fixme 具体位置不显示
          }
        }
        var container_in = Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                _string,
                style: TextStyle(color: Colors.white, fontSize: px.x(60)),
              ),
              StatefulBuilder(
                  builder: (BuildContext context, StateSetter setState) {
                var _text = DateTimeUtils.getDateTimeWithTime();
                // realtimeRefreshUi(
                //     RefreshUi(setState, mounted,
                //         milliseconds: 1000, isRefresh: true), (value) {
                //   value.isRefresh = true; //刷新
                //   value.mounted = mounted; //fixme mounted要实时更新，判断当前组件是否销毁
                //   return value;
                // });
                return Text(
                  _text,
                  style: TextStyle(color: Colors.white, fontSize: px.x(36)),
                );
              })
            ],
          ),
          width: px.x(350),
          height: px.x(350),
          decoration: BoxDecoration(
            //color: color_circle_in,
            borderRadius: BorderRadius.all(Radius.circular(400)),
          ),
        );
        var container_out = Container(
          child: Material(
            color: color_circle_in,
            borderRadius: BorderRadius.all(Radius.circular(400)), //圆角
            child: InkWell(
              child: container_in,
              onTap: () {
                //fixme 打卡
                presenter?.clockin(context);
              },
              borderRadius: BorderRadius.all(Radius.circular(400)),
              //圆角
              //splashColor: Colors.transparent,
              // 溅墨色（波纹色）
              //highlightColor: Colors.transparent,
              // 点击时的背景色（高亮色）
              //hoverColor: color_circle_in,
              //鼠标悬浮时颜色
              //focusColor: color_circle_in,
            ),
          ),
          alignment: Alignment.center,
          width: px.x(400),
          height: px.x(400),
          decoration: BoxDecoration(
            color: color_circle_out,
            borderRadius: BorderRadius.all(Radius.circular(400)),
          ),
        );
        var column = Column(
          children: [
            container_out,
            Padding(
              padding: EdgeInsets.only(top: px.x(40)),
              child: Text(
                attendance,
                style:
                    TextStyle(color: attendanceTextColor, fontSize: px.x(36)),
              ),
            )
          ],
        );
        return Container(
          child: column,
          alignment: Alignment.center,
          margin: EdgeInsets.only(top: px.y(50)),
        );
      },
    );
  }

  ///打卡底部按钮信息;显示上班已打卡，或未打卡信息
  Widget _clockinInfo(BuildContext context) {
    List<Widget> children = [];
    var _fontSize = px.x(36);
    var _width = px.x(450);
    var _height = px.x(160);
    //fixme 上班
    bool isOnWork = presenter?.isOnWorkClockin() ?? false; //判断上班是否已打卡
    if (isOnWork) {
      //fixme 上班已打卡
      ClockinInfo? workInfo = presenter?.clokinData?.WorkInfo;
      //打卡班次信息
      MyAttendances? attachment = workInfo?.getAttendance();
      //班次名称
      Text text = Text(
        attachment?.WorkTypeName ?? "",
        style: TextStyle(color: Colors.black, fontSize: 18),
      );
      List<Widget> _children = [];
      //上班打卡时间
      Text text1 = Text(
        AppStrings.of(context).punchIn + " ${workInfo?.formatOnWorkTime()}",
        style: TextStyle(
            color: ColorUtils.parseColor("#666666"), fontSize: _fontSize),
      );
      _children.add(text1);
      if (workInfo?.islate() ?? false) {
        //fixme 迟到
        Text text2 = Text(
          " " + AppStrings.of(context).late,
          style: TextStyle(
              color: ColorUtils.parseColor("#ef5a25"), fontSize: _fontSize),
        );
        _children.add(text2);
      }
      var row = Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: _children,
      );
      var column = Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [text, row],
      );
      var container = Container(
          child: column,
          alignment: Alignment.center,
          margin: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 10),
          width: _width,
          height: _height,
          decoration: BoxDecoration(
            color: ColorUtils.parseColor("#D4E1F3"),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ));
      children.add(InkWell(
        child: container,
        onTap: () {
          AppRouteHelper.goClockinRecordRoute(context);
        },
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ));
    } else {
      //fixme 上班未打卡
      Text text = Text(
        AppStrings.of(context).gotoWork +
            " " +
            AppStrings.of(context).notClockIn,
        style: TextStyle(
            color: ColorUtils.parseColor("#aaaaaa"), fontSize: _fontSize),
      );
      var container = Container(
          child: text,
          alignment: Alignment.center,
          margin: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 10),
          width: _width,
          height: _height,
          decoration: BoxDecoration(
            color: ColorUtils.parseColor("#D4E1F3"),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ));
      children.add(InkWell(
        child: container,
        onTap: () {
          //fixme 跳转打卡记录
          AppRouteHelper.goClockinRecordRoute(context);
        },
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ));
    }
    //fixme 下班
    bool isOffWork = presenter?.isOffWorkClockin() ?? false; //判断下班是否已打卡
    if (isOffWork) {
      //fixme 下班已打卡
      ClockinInfo? workInfo = presenter?.clokinData?.WorkInfo;
      //打卡班次信息
      MyAttendances? attachment = workInfo?.getAttendance();
      //班次名称
      Text text = Text(
        attachment?.WorkTypeName ?? "",
        style: TextStyle(color: Colors.black, fontSize: 18),
      );
      List<Widget> _children = [];
      //下班打卡时间
      Text text1 = Text(
        AppStrings.of(context).punchOut + " ${workInfo?.formatOffWorkTime()}",
        style: TextStyle(
            color: ColorUtils.parseColor("#666666"), fontSize: _fontSize),
      );
      _children.add(text1);
      if (workInfo?.isleaveEarly() ?? false) {
        //fixme 早退
        Text text2 = Text(
          " " + AppStrings.of(context).leaveEarly,
          style: TextStyle(
              color: ColorUtils.parseColor("#ef5a25"), fontSize: _fontSize),
        );
        _children.add(text2);
      }
      var row = Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: _children,
      );
      var column = Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [text, row],
      );
      var container = Container(
          child: column,
          alignment: Alignment.center,
          margin: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 10),
          width: _width,
          height: _height,
          decoration: BoxDecoration(
            color: ColorUtils.parseColor("#D4E1F3"),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ));
      children.add(InkWell(
        child: container,
        onTap: () {
          AppRouteHelper.goClockinRecordRoute(context);
        },
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ));
    } else {
      //fixme 下班未打卡
      Text text = Text(
        AppStrings.of(context).afterWork +
            " " +
            AppStrings.of(context).notClockIn,
        style: TextStyle(
            color: ColorUtils.parseColor("#aaaaaa"), fontSize: _fontSize),
      );
      var container = Container(
          child: text,
          alignment: Alignment.center,
          width: _width,
          height: _height,
          margin: EdgeInsets.only(top: 5, bottom: 5, left: 10, right: 0),
          decoration: BoxDecoration(
            color: ColorUtils.parseColor("#D4E1F3"),
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ));
      children.add(InkWell(
        child: container,
        onTap: () {
          AppRouteHelper.goClockinRecordRoute(context);
        },
        splashColor: Colors.transparent,
        highlightColor: Colors.transparent,
      ));
    }
    //--------------------------------------------------------------------------
    var row = Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: children,
    );
    return Container(
      child: row,
      alignment: Alignment.bottomCenter,
      margin: EdgeInsets.only(top: px.y(200)),
    );
  }
}

class _Presenter {
  StateSetter? setState = null;
  ClokinPointRange? clokinData = null;

  ///fixme 判断当前状态是否为正在上班的状态。 true 已经上班打过卡。下班未打卡。
  bool isOnWork() {
    return clokinData?.isOnWork() ?? false;
  }

  ///判断当前状态是否为应该去上班打卡;true 应该上班打卡；false 应该去下班打卡。
  bool isGoToWork() {
    if (isOnWork()) {
      return false; //已经上班打卡，必须去下班打卡。
    }
    return true; //默认上班打卡。
  }

  //判断当前选中班组班次和服务器记录的班组班次是否一致。
  bool isSameId() {
    if (GroupBcInfo?.GroupId == clokinData?.WorkInfo?.GroupBcInfo?.GroupId &&
        attendances?.AttendanceId ==
            clokinData?.WorkInfo?.getAttendance()?.AttendanceId) {
      return true;
    }
    return false;
  }

  ///判断是否已经上班打卡签到
  bool isOnWorkClockin() {
    if (isOnWork()) {
      return true;
    }
    if (isOffWorkClockin()) {
      return true; //有下班打卡记录，肯定就有上班打卡记录。
    }
    return false;
  }

  ///判断是否已经下班打卡签到
  bool isOffWorkClockin() {
    if (clokinData?.isOffWork() ?? false) {
      //下班已打卡，并且当前选中班组班次和服务器记录的班组班次一致。
      if (isSameId()) {
        return true;
      }
    }
    return false;
  }

  //選中班組
  MyGroupBcInfo? GroupBcInfo = null;

  //选中班次
  MyAttendances? attendances = null;

  _Presenter() {
    ///获取班组班次
    getLocalGroup();
  }

  ///保存本地班组和班次
  saveLocalGroup() {
    if (GroupBcInfo != null && attendances != null) {
      prefs()?.setString(AppKey.getGroupBcInfoKey(), GroupBcInfo?.jsonEncode());
      prefs()?.setString(AppKey.getAttendancesKey(), attendances?.jsonEncode());
    }
  }

  ///获取本地保存的班组班次
  getLocalGroup() {
    if (GroupBcInfo == null && attendances == null) {
      var json = prefs()?.getString(AppKey.getGroupBcInfoKey());
      if (json != null) {
        GroupBcInfo = MyGroupBcInfo();
        GsonUtils.parseJson(json, GroupBcInfo);
      }
      var json2 = prefs()?.getString(AppKey.getAttendancesKey());
      if (json2 != null) {
        attendances = MyAttendances();
        GsonUtils.parseJson(json2, attendances);
      }
    }
  }

  //定位信息
  BaiduMapLocation? location = null;

  //fixme 定位显示的地点名称;界面显示的地面名称是这个值。
  String? adress = "";

  //考勤范围在经纬度100米范围内。
  bool isLessthan_100 = true;

  bool _isField = false; //true 外勤打卡，false 正常打卡。

  ///判断是否外勤打卡
  bool isField() {
    var longitude = clokinData?.getLongitude(); //公司经度
    var latitude = clokinData?.getLatitude(); //公司纬度
    var signInRange = clokinData?.getSignInRange(); //范围判断
    if (clokinData != null) {
      if (StringUtils.isEmpty(clokinData?.BaiduMapPoint)) {
        _isField = false;
        return false; //经纬度为空，不需要判断考勤范围。
      }
      if (signInRange != null && signInRange <= 0) {
        _isField = false;
        return false; //不需要判断考勤范围。
      }
    }
    if (signInRange != null &&
        signInRange > 0 &&
        longitude != null &&
        latitude != null) {
      var lng1 = location?.longitude;
      var lat1 = location?.latitude;
      if (lng1 != null && lat1 != null) {
        var distance =
            BaiduMapUtils.getDistance(lng1, lat1, longitude, latitude);
        //print("考勤范围:$distance");//考勤范围:68.6
        if (distance <= signInRange) {
          if (distance <= 100) {
            isLessthan_100 = true;
          } else {
            isLessthan_100 = false;
          }
          _isField = false;
          return false;
        } else {
          isLessthan_100 = false;
        }
      }
    }
    _isField = true;
    return true;
  }

  ///获取经纬度度，班组班次信息。(最新的打卡记录)
  getAppSignInHandlerWithGetPointRange(BuildContext context,
      {ResponseCallbackWithBool? responseCallbackWithBool = null,
      bool isEnableLoad = true}) {
    Future.delayed(Duration(milliseconds: 200)).then((value) {
      ClokinModel.getAppSignInHandlerWithGetPointRange(context, isEnableLoad,
          (value) {
        dismissDialogWithLoad(context); //fixme 关闭弹窗。防止异常无法关闭。
        if (value != null) {
          if (value.isSuccessForCode()) {
            //成功
            setState?.call(() {
              clokinData = value.Data;
              if (GroupBcInfo == null) {
                //fixme 班组信息为空，默认为服务器最新的打卡签到的班组。
                GroupBcInfo = clokinData?.WorkInfo?.GroupBcInfo;
                attendances = clokinData?.WorkInfo?.getAttendance();
              }
              if (GroupBcInfo != null) {
                //验证缓存班组是否存在。(防止班组数据更新)
                var hasGroup = false;
                clokinData?.GroupBcInfo?.forEach((element) {
                  if (element.GroupId == GroupBcInfo?.GroupId) {
                    GroupBcInfo = element; //fixme 以服务器为准；防止是否拍照等信息没有及时更新。
                    hasGroup = true;
                  }
                });
                if (!hasGroup) {
                  //服务器不存在该班组；说明该班组已过期
                  GroupBcInfo = null;
                  attendances = null;
                }
              }
              if (clokinData?.isOnWork() ?? false) {
                ///fixme 用户已经签到打过卡
                GroupBcInfo = clokinData?.WorkInfo?.GroupBcInfo;
                attendances = clokinData?.WorkInfo?.getAttendance();
              } else {
                _GetShifts(context, GroupBcInfo, false); //fixme 刷新班次。
              }
            });
            responseCallbackWithBool?.call(true);
          } else {
            AppDialog.showDialogWithInfo(context, content: value?.MsgDetail);
          }
        }
      });
    });
  }

  ///选择班组
  chooseGroupBcInfo(BuildContext context) {
    if (clokinData == null) {
      //防止数据为空
      getAppSignInHandlerWithGetPointRange(context,
          responseCallbackWithBool: (value) {
        if (value) {
          //上班已打卡，就不能再选择其他班组了。
          if (!isOnWork()) {
            //上班未打卡
            _chooseGroupBcInfo(context);
          } else {
            //上班已打卡
            //你已在其他班组打卡签到，请先签出再选择其他班组。
            String content = AppStrings.of(context).anotherGroup;
            showDialogWithInfo(context, content: content);
          }
        }
      });
      return;
    } else {
      //上班已打卡，就不能再选择其他班组了。
      if (!isOnWork()) {
        //上班未打卡
        _chooseGroupBcInfo(context);
      } else {
        //上班已打卡
        //你已在其他班组打卡签到，请先签出再选择其他班组。
        String content = AppStrings.of(context).anotherGroup;
        showDialogWithInfo(context, content: content);
      }
    }
  }

  ///选择班组
  _chooseGroupBcInfo(BuildContext context) {
    if (StringUtils.isEmpty(clokinData?.GroupBcInfo)) {
      //该无班组信息
      AppDialog.showDialogWithInfo(context,
          content: AppStrings.of(context).GroupBcInfoEmpty);
      return;
    }
    //print("班组：${presenter.clokinData?.GroupBcInfo.toString()}");
    showDialogWithClass(context,
            content: clokinData?.GroupBcInfo, value: GroupBcInfo?.GroupId)
        ?.then((value) {
      if (value != null) {
        _GetShifts(context, value, true);
        // if (StringUtils.isNotEmpty(value.Attendances)) {
        //   setState?.call(() {
        //     //print("选中班组$value");
        //     if (GroupBcInfo?.GroupId != value.GroupId) {
        //       attendances = null; //班组发生变化，班次重置。
        //     }
        //     GroupBcInfo = value;
        //   });
        // } else {
        //   //该班组暂无班次信息，请重新选择班组;fixme 班次信息需要请求二次接口获得。
        //   AppDialog.showDialogWithInfo(context,
        //       content: AppStrings.of(context).GroupBcInfoError);
        // }
      }
    });
  }

  ///根据班组请求班次。
  ///isHand true 用户手动选择的班组；false 页面自动刷新，判断当前班次是否正常。
  _GetShifts(
      BuildContext context, MyGroupBcInfo? valueGroupBcInfo, bool isHand) {
    if (valueGroupBcInfo != null) {
      ClokinModel.GetShifts(context, true, valueGroupBcInfo, (value) {
        if (value.isSuccessForCode()) {
          if (GroupBcInfo?.GroupId != valueGroupBcInfo?.GroupId) {
            attendances = null; //班组发生变化，班次重置。
          }
          GroupBcInfo = valueGroupBcInfo;
          if (value?.Data != null) {
            List<MyAttendances> _Attendances = value!.Data!;
            GroupBcInfo?.Attendances = _Attendances; //fixme 将班次集合，复制到对应的班组上。
            if (_Attendances != null && _Attendances!.length == 1) {
              attendances = _Attendances![0]; //只有一个必选。
            } else {
              var hasAtte = false;
              _Attendances?.forEach((element) {
                if (element.AttendanceId == attendances?.AttendanceId) {
                  hasAtte = true;
                  attendances = element; //fixme 班次更新，以服务器的为准。
                }
              });
              if (!hasAtte) {
                //服务器不存在该班次
                attendances = null;
              }
            }
          }
          setState?.call(() {}); //页面刷新
        } else {
          if (!isHand) {
            //fixme 页面自动刷新数据；主要是为了页面首次进入时，自动验证上一次缓存的班组班次数据是否为正确的数据。
            GroupBcInfo = null;
            attendances = null;
          } else {
            AppDialog.showDialogWithInfo(context, content: value?.MsgDetail);
          }
        }
      });
    }
  }

  ///fixme 打卡
  void clockin(BuildContext context) {
    //fixme 测试，直接跳转到打卡结果页面
    // AppRouteHelper.goClockinResultRoute(context, "打卡成功");
    // return;
    if (GroupBcInfo == null) {
      //请先选择签到班组
      AppDialog.showDialogWithInfo(context,
          content: AppStrings.of(context).PleaseGroupBcInfo);
      return;
    }
    if (attendances == null) {
      if (isOnWork()) {
        //fixme 这里，如果是正处于上班状态，是禁止用户手动选择班组班次的；
        //fixme 如果这里班次为空。那肯定是服务器返回的空。所以不拦截这个情况。以防万一用户无法正常下班打卡。
      } else {
        //请先选择签到班次
        AppDialog.showDialogWithInfo(context,
            content: AppStrings.of(context).PleaseShift);
        return;
      }
    }
    if (_isField) {
      //外勤打卡提示
      //当前定位判定为外勤打卡，是否继续打卡?
      var fieldClock2 = AppStrings.of(context).fieldClock2;
      showDialogWithAlert(context, content: fieldClock2)?.then((value) {
        if (value ?? false) {
          _clockin(context);
        }
      });
    } else {
      //正常打卡
      _clockin(context);
    }
  }

  _clockin(BuildContext context) {
    ClokinSubmit clokinSubmit = ClokinSubmit.getClokinSubmit(
        GroupBcInfo, attendances,
        Adress: adress, imageUrl: "", isOnWorkField: _isField);
    //不需要拍照
    if (isGoToWork() ?? false) {
      //上班打卡
      clokinSubmit.type = ClokinSubDataType.CheckTimeIn;
    } else {
      //下班打卡
      clokinSubmit.type = ClokinSubDataType.CheckTimeOut;
    }
    checkTimeHandler(context, clokinSubmit);
  }

  ///fixme 打卡提交
  ///isOffWork 判断是否为下班打卡；
  checkTimeHandler(BuildContext context, ClokinSubmit clokinSubmit) {
    var isOffWork = clokinSubmit.isOffWork(); //判断是否为下班打卡
    if (isOffWork) {
      //fixme 下班打卡
      ClokinSubmit clokinSubmit2 = clokinSubmit.copy(); //fixme 复制，这里记得改Type
      clokinSubmit2.type = ClokinSubDataType.GetSignOut;
      ClokinModel.isCheckTimeHandler(context, true, clokinSubmit2, (value) {
        if (value != null) {
          if (value.isSuccessForCode()) {
            //可以正常下班签退
            _checkTimeHandler(context, clokinSubmit, isOffWork);
          } else if (value.isSuccessForCode102()) {
            //var data = value;
            //fixme 签退打卡需要二次确认
            showDialogWithAlert(context, content: value.MsgDetail)
                ?.then((value) {
              if (value ?? false) {
                _checkTimeHandler(context, clokinSubmit, isOffWork);
              }
            });
          } else {
            AppDialog.showDialogWithInfo(context, content: value?.MsgDetail);
          }
        }
      });
    } else {
      //fixme 上班打卡
      _checkTimeHandler(context, clokinSubmit, isOffWork);
    }
  }

  //isOffWork 判断是否为下班打卡。
  _checkTimeHandler(
      BuildContext context, ClokinSubmit clokinSubmit, bool isOffWork) {
    // print("=====================================================================进来打卡$isOffWork");
    if (GroupBcInfo!.isTakePic()) {
      //fixme 需要拍照
      LibRouteHelper.goCameraRoute(context, (value) {
        // print("=================================================================拍照图片：${value?.path}");
        if (StringUtils.isEmpty(value?.path)) {
          //相机拍照失败，请重新拍照
          AppDialog.showDialogWithInfo(context,
              content: AppStrings.of(context).Takephotostoplay2);
          return;
        }
        if (value.path != null) {
          var path = value!.path!;
          List<File> files = FileUtils.getFilesWithFile(value);
          if (files == null || files.length <= 0) {
            //相机拍照失败，请重新拍照
            AppDialog.showDialogWithInfo(context,
                content: AppStrings.of(context).Takephotostoplay2);
            return;
          }
          // print("===============================================================图片上传");
          UserModel.syspicupload(context, true, files, (value) {
            // print(
            //     "========================================================图片地址：${value.Data}");
            if (StringUtils.isEmpty(value?.Data)) {
              //图片上传失败，请重新拍照打卡
              AppDialog.showDialogWithInfo(context,
                  content: AppStrings.of(context).Takephotostoplay);
            } else {
              var url = value.Data!; //网络地址
              FileUtils.delFile(path); //删除本地图片
              clokinSubmit.OnWorkImageUrl = url;
              _checkTimeHandler2(context, clokinSubmit, isOffWork);
            }
          });
        }
      }, pre: true);
    } else {
      //fixme 不需要拍照
      _checkTimeHandler2(context, clokinSubmit, isOffWork);
    }
  }

  _checkTimeHandler2(
      BuildContext context, ClokinSubmit clokinSubmit, bool isOffWork) {
    // print("=====================================================================打卡：$isOffWork");
    if (isOffWork) {
      //fixme 下班打卡
      ClokinModel.CheckTimeOut(context, true, clokinSubmit, (value) {
        if (value != null) {
          //fixme 下班打卡成功
          if (value.isSuccessForCode() ||
              value.isSuccessForCode102() ||
              value.isSuccessForCode103()) {
            //打卡成功，跳转到打卡结果页面
            var is102 = true;
            //下班打卡成功
            if (value.isSuccessForCode102() || value.isSuccessForCode103()) {
              ClokinModel.wageField = value.Data;
              if (value.isSuccessForCode103()) {
                is102 = false; //102 当日结算 103本次结算
              }
            } else {
              ClokinModel.wageField = null;
            }
            //print("参数========================================================= ${ClokinModel.wageField?.code}\t ${value?.Data?.code}");
            AppRouteHelper.goClockinResultRoute(context, value.MsgDetail,
                isOffWork: isOffWork, is102: is102);
          } else {
            AppDialog.showDialogWithInfo(context, content: value?.MsgDetail);
          }
        }
      });
    } else {
      //fixme 上班打卡
      ClokinModel.CheckTimeIn(context, true, clokinSubmit, (value) {
        if (value != null) {
          //fixme 上班打卡成功
          if (value.isSuccessForCode()) {
            //打卡成功，跳转到打卡结果页面
            var is102 = true;
            ClokinModel.wageField = null;
            AppRouteHelper.goClockinResultRoute(context, value.MsgDetail,
                isOffWork: isOffWork, is102: is102);
          } else {
            AppDialog.showDialogWithInfo(context, content: value?.MsgDetail);
          }
        }
      });
    }
  }
}
